#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <cstring>
#include <strings.h>
#include <string>
#include<cerrno>
#include "ERRNO.hpp"
#include"protocol.hpp"


using namespace std;

void ClientHandler(int sock,string severip,uint16_t severport)
{
    //简单点，就规定输入必须是 _x _op _y,中间带一个空格a
    string inbuffer;
    while(1)
    {
        //1 
        Request rq; 
        cin>>rq._x;
        cin>>rq._op;
        cin>>rq._y;
        // cout<<"cin :"<<rq._x<<rq._op<<rq._y<<endl;
        //2
        string Send = EnHeader(rq.Serialize());
        //3 
        // cout<<"Send:"<<Send<<endl;
        int n = write(sock,Send.c_str(),Send.size());
        if(n==-1)
        {
            cout<<"Write error"<<endl;
            exit(WRITE_ERR);
        }
        (void)n;
        //4
        string outbuffer;
        ReadOneText(sock,outbuffer,inbuffer);
        //5
        // cout<<"RECV:"<<outbuffer<<endl;
        Response res;
        res.Deserialize(outbuffer);
        if(res._exitcode != NORMAL) 
        {
            protocolerr(res._exitcode); //设计一个打印错误类型的函数
        }
        else
        cout<<"the result is : "<<res._result<<endl;
    }
}



class client
{
public:
    client(uint16_t port, string ip)
        : _severport(port), _severip(ip)
    {
    }
    void init()
    {
        _sock = socket(AF_INET, SOCK_STREAM, 0);
        if (_sock == -1)
        {
            cout << "socket fail" << endl;
            // cout<<strerror(errno)<<endl;
            exit(SOCKET_ERR);
        }
        cout << "socket success" << endl;
        //不需要显式bind
    }
    void start()
    {
        struct sockaddr_in sever;
        sever.sin_addr.s_addr = inet_addr(_severip.c_str());
        sever.sin_port = htons(_severport);
        sever.sin_family = AF_INET;
        socklen_t len = sizeof sever;
        int n = connect(_sock,(struct sockaddr*)&sever,len);
        if(n!=0) 
        {
            cout<<"connect fail"<<endl;
            cout<<strerror(errno)<<endl;
            exit(CONNECT_ERR);
        }
        cout<<"connect success"<<endl;
        // 连接成功之后就是客户端的请求逻辑
        ClientHandler(_sock,_severip,_severport);
    
    }   

private:
    int _sock;
    string _severip;
    uint16_t _severport;
};
